package com.zhang.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhang.common.util.result.R;
import com.zhang.common.util.result.RUtils;
import com.zhang.order.config.AliPayConfig;
import com.zhang.order.entity.Order;
import com.zhang.order.entity.OrderItem;
import com.zhang.order.service.IOrderItemService;
import com.zhang.order.service.IOrderService;
import com.zhang.order.service.IPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.alipay.api.AlipayConstants.CHARSET;
import static com.alipay.api.AlipayConstants.SIGN_TYPE;

/**
 * 沙箱支付
 *
 * @author hongmizfb
 * @date 2024/06/16
 */
@Service
@Slf4j
public class AliPaySandBoxServiceImpl implements IPayService {
    @Autowired
    private AliPayConfig aliPayConfig;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderItemService orderItemService;

    @Override
    public R pay(String orderId) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getId, Long.valueOf(orderId));
        wrapper.eq(Order::getStatus, 0);
        Order one = orderService.getOne(wrapper);
        if (one == null) {
            return RUtils.err("订单不存在");
        }
        List<OrderItem> listByOrderId = orderItemService.getListByOrderId(one.getId());
//        取第一个订单项中的商品名为订单标题
        String orderTitle = listByOrderId.get(0).getSpuName();
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getServerUrl(), aliPayConfig.getAppId(), aliPayConfig.getPrivateKey(), "json", "UTF-8", aliPayConfig.getAlipayPublicKey(), "RSA2");
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
//异步接收地址，仅支持http/https，公网可访问
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
//同步跳转地址，仅支持http/https
        request.setReturnUrl(aliPayConfig.getReturnUrl() + one.getId());
/******必传参数******/
        JSONObject bizContent = new JSONObject();
//商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", one.getId());
//支付金额，最小值0.01元
        bizContent.put("total_amount", one.getPayAmount().doubleValue());//转成double，支付宝沙箱不支持BigDecimal
//订单标题，不可使用特殊符号
        bizContent.put("subject", "购买" + orderTitle);
//电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

/******可选参数******/
//bizContent.put("time_expire", "2022-08-01 22:00:00");

//// 商品明细信息，按需传入
//JSONArray goodsDetail = new JSONArray();
//JSONObject goods1 = new JSONObject();
//goods1.put("goods_id", "goodsNo1");
//goods1.put("goods_name", "子商品1");
//goods1.put("quantity", 1);
//goods1.put("price", 0.01);
//goodsDetail.add(goods1);
//bizContent.put("goods_detail", goodsDetail);

//// 扩展信息，按需传入
//JSONObject extendParams = new JSONObject();
//extendParams.put("sys_service_provider_id", "2088511833207846");
//bizContent.put("extend_params", extendParams);
        request.setBizContent(bizContent.toString());
        AlipayTradePagePayResponse response = null;
        try {
            response = alipayClient.pageExecute(request, "POST");
        } catch (AlipayApiException e) {
            return RUtils.err("失败");
        }
// 如果需要返回GET请求，请使用
// AlipayTradePagePayResponse response = alipayClient.pageExecute(request,"GET");
        String pageRedirectionData = response.getBody();
        if (response.isSuccess()) {
            return RUtils.successData(pageRedirectionData);
        } else {
            log.error("返回失败{}", String.valueOf(response));
            return RUtils.err("返回失败");
        }

    }

    @Override
    public R payNotify(HttpServletRequest request) {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }
            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            Long orderId = Long.valueOf(params.get("out_trade_no"));
            // 支付宝验签
            boolean signVerified = false;  //调用SDK验证签名
            try {
                signVerified = AlipaySignature.rsaCheckV1(params, aliPayConfig.getAlipayPublicKey(), CHARSET, SIGN_TYPE);
            } catch (AlipayApiException e) {
                throw new RuntimeException(e);
            }
            if (signVerified) {
                //验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商家自身业务处理，校验失败返回failure
                // 验签通过
/*                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));*/
                // 更新订单为已支付
                Order order = new Order();
                order.setId(orderId);
                order.setOrderSn(tradeNo);
                order.setPaymentTime(params.get("gmt_payment"));
                order.setPayType(1);//支付宝方式
                orderService.updateOrderToPay(order);
            } else {
                //  验签失败则记录异常日志，并在response中返回failure.
                System.err.println("支付宝沙箱验签失败");
                return RUtils.err("支付结果异常");
            }
        }
        return RUtils.successMsg("支付成功");
    }

    @Override
    public R queryOrderPayResult(String orderId) {
        Order byId = orderService.getById(orderId);
        if (byId == null) {
            return RUtils.err("订单不存在");
        }
        if (1 == byId.getStatus()) {
            return RUtils.success();
        }
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getServerUrl(), aliPayConfig.getAppId(), aliPayConfig.getPrivateKey(), "json", "UTF-8", aliPayConfig.getAlipayPublicKey(), "RSA2");
        // 构造请求参数以调用接口
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(orderId);
        // 设置银行间联模式下有用
//    model.setOrgPid("2088101117952222");
        // 设置查询选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("trade_settle_info");
        model.setQueryOptions(queryOptions);
        // 设置支付宝交易号
        model.setTradeNo(byId.getOrderSn());
        request.setBizModel(model);
        AlipayTradeQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        System.out.println("响应结果：" + response.getBody());
        Map<String, Map<String, String>> result = JSON.parseObject(response.getBody(), Map.class);//将响应结果转换为map
        /*分析结果*/
        Map<String, String> alipay_trade_query_response = result.get("alipay_trade_query_response");
        System.out.println("alipay_trade_query_response" + alipay_trade_query_response);
        String trade_status = alipay_trade_query_response.get("trade_status");
        String trade_no = alipay_trade_query_response.get("trade_no");
        System.out.println("trade_no" + trade_no);
        String send_pay_date = alipay_trade_query_response.get("send_pay_date");
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
        if ("TRADE_SUCCESS".equals(trade_status)) {
            Order order = new Order();
            order.setId(Long.valueOf(orderId));
            order.setOrderSn(trade_no);
            order.setStatus(1);
            order.setPayType(1);//支付宝方式
            order.setPaymentTime(send_pay_date);
            orderService.updateOrderToPay(order);
            return RUtils.successMsg("支付成功");
        }
        return RUtils.err("支付失败");
    }
}
